﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Core;
using Alos;
using System.Net;
using Newtonsoft.Json;
using Model;
using System.Threading.Tasks;
using System.Threading;
using PresentationControls;

namespace Alos
{
    public partial class FormMain : Form
    {
        static List<IGrouping<string, SimpleRoomInfo>> gpRoom = new List<IGrouping<string, SimpleRoomInfo>>();
        static List<BasicSchoolInfo> schoolSet = new List<BasicSchoolInfo>();
        static object objBaseData = new object();
        public FormMain()
        {
            InitializeComponent();
            AddFireWall();
            InitData();
        }

        private void btnInstallUninstallService_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            if (btnInstallUninstallService.Text.IndexOf("安装") >= 0)
            {
                if (ConfigHelper.GetConfigInt("SchoolID") <= 0)
                {
                    MessageBox.Show("请先选择所在学校！");
                    this.Cursor = Cursors.Arrow;
                    return;
                }
                if (string.IsNullOrWhiteSpace(ConfigHelper.GetConfigString("RoomID")))
                {
                    MessageBox.Show("请先选择所在班级！");
                    this.Cursor = Cursors.Arrow;
                    return;
                }
                try
                {
                    if (WindowsServiceManager.IsServiceExisted(AlosService.Name))
                    {
                        WindowsServiceManager.UnInstallService(AlosService.Name);
                    }

                    WindowsServiceManager.InstallService(AlosService.Name);
                    btnInstallUninstallService.Text = "卸载服务";
                    MessageBox.Show("服务安装成功！");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                try
                {
                    if (WindowsServiceManager.IsServiceExisted(AlosService.Name))
                    {
                        WindowsServiceManager.UnInstallService(AlosService.Name);
                    }
                    btnInstallUninstallService.Text = "安装服务";
                    RemoveFireWall();
                    MessageBox.Show("服务卸载成功！");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

            this.Cursor = Cursors.Arrow;
        }

        private void btnStartStopService_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            if (btnStartStopService.Text.IndexOf("启动") >= 0)
            {
                if (ConfigHelper.GetConfigInt("SchoolID") <= 0)
                {
                    MessageBox.Show("请先选择所在学校！");
                    this.Cursor = Cursors.Arrow;
                    return;
                }
                if (string.IsNullOrWhiteSpace(ConfigHelper.GetConfigString("RoomID")))
                {
                    MessageBox.Show("请先选择所在班级！");
                    this.Cursor = Cursors.Arrow;
                    return;
                }
                StopAndStartService();
                btnStartStopService.Text = "停止服务";
            }
            else
            {
                WindowsServiceManager.StopService(AlosService.Name);
                btnStartStopService.Text = "启动服务";
            }

            this.Cursor = Cursors.Arrow;
        }


        public void StopAndStartService()
        {
            if (WindowsServiceManager.IsServiceStarted(AlosService.Name))
            {
                WindowsServiceManager.StopService(AlosService.Name);
            }

            WindowsServiceManager.StartService(AlosService.Name);
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            RefreshStatus();
        }


        public void RefreshStatus()
        {
            try
            {
                lblServiceStatus.Text = "";

                if (!WindowsServiceManager.IsServiceExisted(AlosService.Name))
                {
                    lblServiceStatus.Text = "服务未安装";
                    lblServiceStatus.ForeColor = Color.Red;
                    btnInstallUninstallService.Text = "安装服务(&I)";
                    return;
                }

                btnInstallUninstallService.Text = "卸载服务(&U)";

                if (!WindowsServiceManager.IsServiceStarted(AlosService.Name))
                {
                    lblServiceStatus.Text = "服务已停止";
                    lblServiceStatus.ForeColor = Color.Red;
                    btnStartStopService.Text = "启动服务(&S)";
                    return;
                }

                lblServiceStatus.Text = "服务已启动";
                lblServiceStatus.ForeColor = Color.DarkGreen;
                btnStartStopService.Text = "停止服务(&S)";

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            RefreshStatus();
        }
        private void SetAsyncType()
        {
            List<ComboboxItem> dic = new List<ComboboxItem>();
            dic.Add(new ComboboxItem() { Text = "校园网部署", Value = 0 });
            dic.Add(new ComboboxItem() { Text = "互联网部署", Value = 2 });
            cmbLessionAsyncType.DataSource = dic;
            cmbLessionAsyncType.DisplayMember = "Text";
            cmbLessionAsyncType.ValueMember = "Value";
            int latp = ConfigHelper.GetConfigInt("LessionAsyncType");
            cmbLessionAsyncType.SelectedValue = latp;
        }
        private void SetSchool(bool async = false)
        {
            WebClient wc = new WebClient();
            wc.Encoding = System.Text.Encoding.GetEncoding("utf-8");
            string school = string.Empty;
            try
            {
                school = wc.DownloadString(ConfigHelper.GetConfigString("RemoteUrl") + "/Ayyfford/GetSchool");
                wc.Dispose();
                schoolSet = JsonConvert.DeserializeObject<List<BasicSchoolInfo>>(school);
                if (async)
                {
                    MessageBox.Show("云端地址适配成功！");
                }
            }
            catch (Exception ex)
            {
                if (!async)
                {
                    AsyncShow("云端地址错误，请设置正确的云端地址！");
                    Log.errorlog(ex);
                }
                return;
            }
            int SchoolID = ConfigHelper.GetConfigInt("SchoolID");
            schoolSet.Insert(0, new BasicSchoolInfo() { ID = 0, SchoolName = "请选择学校" });
            cmbSchool.ValueMember = "ID";
            cmbSchool.DisplayMember = "SchoolName";
            cmbSchool.DataSource = schoolSet;
            var curSchool = schoolSet.Find(item => item.ID == SchoolID);
            if (curSchool != null)
            {
                cmbSchool.SelectedValue = SchoolID;
            }
            cmbSchool_SelectedIndexChanged(null, null);
        }
        private void SetSyncTime()
        {
            var sts = ConfigHelper.GetConfigString("SyncTime").Split(';');
            for (var i = 0; i < sts.Length; i++)
            {
                lbxLoadTime.Items.Add(sts[i]);
            }
        }
        private void InitData()
        {
            new Thread(() =>
            {
                Control.CheckForIllegalCrossThreadCalls = false;
                SetAsyncType();
                SetSchool();
                SetSyncTime();
                txtResourceDir.Text = ConfigHelper.GetConfigString("SourceDir");
                txtCloudAddress.Text = ConfigHelper.GetConfigString("RemoteUrl");
                txtPreparingNotation.Text = ConfigHelper.GetConfigString("LocalImgDir");
                txtClassResDir.Text = ConfigHelper.GetConfigString("LocalResDir");
                txtResourceUrl.Text = ConfigHelper.GetConfigString("RemoteSourceUrl");
            }).Start();
        }
        private void cmbSchool_SelectedIndexChanged(object sender, EventArgs e)
        {
            WebClient wc = new WebClient();
            wc.Encoding = System.Text.Encoding.GetEncoding("utf-8");
            List<SimpleRoomInfo> lsri = new List<SimpleRoomInfo>();
            try
            {
                var room = wc.DownloadString(ConfigHelper.GetConfigString("RemoteUrl") + "/Ayyfford/GetRoom/" + cmbSchool.SelectedValue);
                wc.Dispose();
                lsri = JsonConvert.DeserializeObject<List<SimpleRoomInfo>>(room);
            }
            catch (Exception ex)
            {
                MessageBox.Show("云端教室信息异常,请确保每个班级都已正确关联到教室！");
                Application.Exit();
                Log.errorlog(ex);
                return;
            }
            gpRoom = lsri.GroupBy(item => item.GradeInfoId).ToList();
            var grade = new List<SimpleRoomInfo>();
            if (gpRoom != null && gpRoom.Count > 0)
                grade = (from c in gpRoom select new SimpleRoomInfo() { GreadeID = c.FirstOrDefault().GreadeID, GradeInfoId = c.FirstOrDefault().GradeInfoId, GradeName = c.FirstOrDefault().GradeName }).ToList();

            grade.Insert(0, new SimpleRoomInfo() { GreadeID = "0", GradeInfoId = "0", GradeName = "请选择年级" });
            var RoomIDs = ConfigHelper.GetConfigString("RoomID").Split(',');
            int RoomID = RoomIDs.Length > 0 ? Convert.ToInt32(RoomIDs[0]) : 0;
            cmbGrade.DataSource = grade;
            cmbGrade.ValueMember = "GradeInfoId";
            cmbGrade.DisplayMember = "GradeName";

            var selected = lsri.Find(item => item.RoomID == RoomID);
            if (selected != null)
            {
                cmbGrade.SelectedValue = selected.GradeInfoId;
            }
            ConfigHelper.SetConfigString("SchoolID", cmbSchool.SelectedValue.ToString());
            var curSchool = schoolSet.Find(item => item.ID.ToString() == (string.IsNullOrWhiteSpace(cmbSchool.SelectedValue.ToString()) ? ConfigHelper.GetConfigString("SchoolID") : cmbSchool.SelectedValue.ToString()));
            cmbGrade_SelectedIndexChanged(sender, e);
        }

        private void btnReStart_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            if (ConfigHelper.GetConfigInt("SchoolID") <= 0)
            {
                MessageBox.Show("请先选择所在学校！");
                this.Cursor = Cursors.Arrow;
                return;
            }
            if (string.IsNullOrWhiteSpace(ConfigHelper.GetConfigString("RoomID")))
            {
                MessageBox.Show("请先选择所在班级！");
                this.Cursor = Cursors.Arrow;
                return;
            }
            WindowsServiceManager.ReStartService(AlosService.Name);
            MessageBox.Show("服务重启成功！");
            this.Cursor = Cursors.Arrow;
        }

        private void cmbGrade_SelectedIndexChanged(object sender, EventArgs e)
        {
            var RoomSet = gpRoom.Find(item => item.Key == cmbGrade.SelectedValue.ToString());
            var RoomIds = ConfigHelper.GetConfigString("RoomID").Split(',');
            
            List<int> _sedidx = new List<int>();
            if (RoomSet == null)
                return;
            var grade = (from c in RoomSet select new SimpleRoomInfo() { RoomID = c.RoomID, ClassName = c.ClassName, RoomName = c.RoomName, DisplayName = c.DisplayName }).ToList();
            // grade.Insert(0, new SimpleRoomInfo() { RoomID = 0, DisplayName = "请选择班级" });
            grade = grade.OrderBy(gd => gd.OrderName).ToList();

            DataTable dt = new DataTable();
            DataColumn dc1 = new DataColumn("RoomID", typeof(System.String));
            dt.Columns.Add(dc1);
            DataColumn dc2 = new DataColumn("DisplayName", typeof(System.String));
            dt.Columns.Add(dc2);

            for (var i = 0; i < grade.Count; i++)
            {
                if (RoomIds.Contains(grade[i].RoomID.ToString()))
                    _sedidx.Add(i);
                DataRow dr = dt.NewRow();
                dr[0] = grade[i].RoomID;
                dr[1] = grade[i].DisplayName;
                dt.Rows.Add(dr);
            }
            ckmClassRoom.DataSource = dt;
            ckmClassRoom.DisplayMember = "DisplayName";
            ckmClassRoom.ValueMember = "RoomID";

            ckmClassRoom.GetSelectedIndex = (sli) =>
            {
                string roomids = string.Empty, _tmpId = string.Empty;
                sli.ForEach(index =>
                {
                    _tmpId = ((DataRowView)ckmClassRoom.Items[index])[0].ToString();
                    if (!string.IsNullOrWhiteSpace(_tmpId))
                    {
                        roomids += _tmpId + ",";
                    }
                });
                ConfigHelper.SetConfigString("RoomID", roomids.Trim(','));
            };
            ckmClassRoom.SetSelectedIndex(_sedidx);
        }
        private void btnSelectDir_Click(object sender, EventArgs e)
        {
            var fd = new FolderBrowserDialog();
            if (fd.ShowDialog() == DialogResult.OK)
            {
                txtResourceDir.Text = fd.SelectedPath;
                ConfigHelper.SetConfigString("SourceDir", txtResourceDir.Text);

            }
        }

        bool IsSubClassOf(Type type, Type baseType)
        {
            var b = type.BaseType;
            while (b != null)
            {
                if (b.Equals(baseType))
                {
                    return true;
                }
                b = b.BaseType;
            }
            return false;
        }

        private void btnLoadBaseData_Click(object sender, EventArgs e)
        {
            FunHelper.TryAsync(() =>
            {
                Control.CheckForIllegalCrossThreadCalls = false;

                if (Monitor.TryEnter(objBaseData))
                {
                    #region 导入字典表
                    SetBasicDataLoadInfo(this, "开始导入字典表！");
                    SetBasicDataLoadInfo(this, "导入学校类型表！");
                    if (new DAL.DicDataDAL().GetDicSchoolType())
                        SetBasicDataLoadInfo(this, "学校类型表导入成功！");
                    SetBasicDataLoadInfo(this, "导入年级表！");
                    if (new DAL.DicDataDAL().GetDicGrade())
                        SetBasicDataLoadInfo(this, "年级表导入成功！");
                    SetBasicDataLoadInfo(this, "导入地区表！");
                    if (new DAL.DicDataDAL().GetDicArea())
                        SetBasicDataLoadInfo(this, "地区表导入成功！");
                    SetBasicDataLoadInfo(this, "导入学校年级关系表！");
                    if (new DAL.DicDataDAL().GetDicGradeInfo())
                        SetBasicDataLoadInfo(this, "学校年级关系表导入成功！");
                    SetBasicDataLoadInfo(this, "导入教学时间表！");
                    if (new DAL.DicDataDAL().GetDicTeachTime())
                        SetBasicDataLoadInfo(this, "教学时间表导入成功！");
                    SetBasicDataLoadInfo(this, "导入学科表！");
                    if (new DAL.DicDataDAL().GetDicSubject())
                        SetBasicDataLoadInfo(this, "学科表导入成功！");
                    SetBasicDataLoadInfo(this, "导入试题类型表！");
                    if (new DAL.DicDataDAL().GetDicQuestionType())
                        SetBasicDataLoadInfo(this, "试题类型表导入成功！");
                    SetBasicDataLoadInfo(this, "导入资源类型表！");
                    if (new DAL.DicDataDAL().GetDicResourceType())
                        SetBasicDataLoadInfo(this, "资源类型表导入成功！");
                    SetBasicDataLoadInfo(this, "导入教师教学行为表！");
                    if (new DAL.DicDataDAL().GetDicTeacherAction())
                        SetBasicDataLoadInfo(this, "教师教学行为表导入成功！");
                    SetBasicDataLoadInfo(this, "导入学生学习行为表！");
                    if (new DAL.DicDataDAL().GetDicStudentAction())
                        SetBasicDataLoadInfo(this, "学生学习行为表导入成功！");
                    SetBasicDataLoadInfo(this, "字典表导入完成！");
                    #endregion

                    #region 导入基础表
                    SetBasicDataLoadInfo(this, "开始导入基础表！");
                    SetBasicDataLoadInfo(this, "导入班级信息表！");
                    if (new DAL.BasicDataLoadDAL().GetBasicClassInfo())
                        SetBasicDataLoadInfo(this, "班级信息表导入成功！");
                    SetBasicDataLoadInfo(this, "导入班级与教师关联表！");
                    if (new DAL.BasicDataLoadDAL().GetBasicClassTERelation())
                        SetBasicDataLoadInfo(this, "班级与教师关联表导入成功！");
                    SetBasicDataLoadInfo(this, "导入学校信息表！");
                    if (new DAL.BasicDataLoadDAL().GetBasicSchoolInfo())
                        SetBasicDataLoadInfo(this, "学校信息表导入成功！");
                    SetBasicDataLoadInfo(this, "导入教室信息表！");
                    if (new DAL.BasicDataLoadDAL().GetBasicRoomInfo())
                        SetBasicDataLoadInfo(this, "教室信息表导入成功！");
                    SetBasicDataLoadInfo(this, "导入教材表！");
                    if (new DAL.BasicDataLoadDAL().GetAllTeachingMaterial())
                        SetBasicDataLoadInfo(this, "教材表导入成功！");
                    SetBasicDataLoadInfo(this, "导入教材绑定表！");
                    if (new DAL.BasicDataLoadDAL().GetAllTeachingMaterialBind())
                        SetBasicDataLoadInfo(this, "教材绑定表导入成功！");
                    SetBasicDataLoadInfo(this, "导入学科知识点表！");
                    if (new DAL.BasicDataLoadDAL().GetBasicKnowledgepoint())
                        SetBasicDataLoadInfo(this, "学科知识点表导入成功！");
                    SetBasicDataLoadInfo(this, "导入章节知识点表！");
                    if (new DAL.BasicDataLoadDAL().GetAllChapter())
                        SetBasicDataLoadInfo(this, "节知识点表导入成功！");
                    SetBasicDataLoadInfo(this, "基础表导入完成！");
                    #endregion

                    #region 导入系统信息表
                    SetBasicDataLoadInfo(this, "导入用户信息表！");
                    if (new DAL.SysUserInfoDAL().GetSysUserInfo())
                        SetBasicDataLoadInfo(this, "用户信息表导入成功！");
                    SetBasicDataLoadInfo(this, "导入角色权限表！");
                    if (new DAL.SysUserInfoDAL().GetSysRoleInfo())
                        SetBasicDataLoadInfo(this, "角色权限表导入成功！");
                    #endregion

                    #region 加载用户头像
                    SetBasicDataLoadInfo(this, "开始下载用户头像！");
                    new DAL.SysUserInfoDAL().DownHeadPhoto();
                    SetBasicDataLoadInfo(this, "用户头像下载完毕！");
                    #endregion
                    Monitor.Exit(objBaseData);
                }
                SetBasicDataLoadInfo(this, "基础数据导入完毕！");
                return true;
            });
        }

        private void btnAddLoadTime_Click(object sender, EventArgs e)
        {
            lbxLoadTime.Items.Add(dtpStart.Value.ToString("HH:mm") + "-" + dtpEnd.Value.ToString("HH:mm"));
            SaveSyncTime();
        }

        private void lbxLoadTime_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            lbxLoadTime.Items.RemoveAt(lbxLoadTime.SelectedIndex);
            SaveSyncTime();
        }
        private void SaveSyncTime()
        {
            string _syncTime = string.Empty;
            foreach (var item in lbxLoadTime.Items)
            {
                _syncTime += item.ToString() + ";";
            }
            ConfigHelper.SetConfigString("SyncTime", _syncTime.TrimEnd(';'));
        }

        private void txtCloudAddress_TextChanged(object sender, EventArgs e)
        {
            ConfigHelper.SetConfigString("RemoteUrl", txtCloudAddress.Text);
        }
        private void AddFireWall()
        {
            Common.Execute("netsh advfirewall firewall delete rule name=\"雅乐视云课堂数据同步服务\"", 10);
            Common.Execute(string.Format("netsh advfirewall firewall add rule name=\"雅乐视云课堂数据同步服务\" description=\"雅乐视服务\" dir=in program=\"{0}\" action=allow", System.Reflection.Assembly.GetEntryAssembly().Location.ToLower()), 10);
            Common.Execute(string.Format("netsh advfirewall firewall add rule name=\"雅乐视云课堂数据同步服务\" description=\"雅乐视服务\" dir=out program=\"{0}\" action=allow", System.Reflection.Assembly.GetEntryAssembly().Location.ToLower()), 10);
        }
        private void RemoveFireWall()
        {
            Common.Execute("netsh advfirewall firewall delete rule name=\"雅乐视云课堂数据同步服务\"", 10);
        }

        private void btnPreparingNotation_Click(object sender, EventArgs e)
        {
            var fd = new FolderBrowserDialog();
            if (fd.ShowDialog() == DialogResult.OK)
            {
                txtPreparingNotation.Text = fd.SelectedPath;
                ConfigHelper.SetConfigString("LocalImgDir", txtPreparingNotation.Text);

            }
        }
        private void SetBasicDataLoadInfo(FormMain fm, string info)
        {
            fm.txtLoadInfo.Text = (string.IsNullOrWhiteSpace(fm.txtLoadInfo.Text) ? "" : "\r\n") + info;
            fm.txtLoadInfo.SelectionStart = fm.txtLoadInfo.Text.Length;
            fm.txtLoadInfo.SelectionLength = 0;
            fm.txtLoadInfo.ScrollToCaret();
            Thread.Sleep(100);
        }

        private void cmbLessionAsyncType_SelectedIndexChanged(object sender, EventArgs e)
        {
            int _val = 0;
            if (int.TryParse(cmbLessionAsyncType.SelectedValue.ToString(), out _val))
                ConfigHelper.SetConfigString("LessionAsyncType", _val.ToString());
        }

        private void txtResourceUrl_TextChanged(object sender, EventArgs e)
        {
            ConfigHelper.SetConfigString("RemoteSourceUrl", txtResourceUrl.Text);
        }

        private void btnClassResNotation_Click(object sender, EventArgs e)
        {
            var fd = new FolderBrowserDialog();
            if (fd.ShowDialog() == DialogResult.OK)
            {
                txtClassResDir.Text = fd.SelectedPath;
                ConfigHelper.SetConfigString("LocalResDir", txtClassResDir.Text);
            }
        }

        private void AsyncShow(string message)
        {
            Core.FunHelper.TryAsync(() =>
            {
                Control.CheckForIllegalCrossThreadCalls = false;
                MessageBox.Show(message);
                return false;
            });
        }

        private void cmbSchool_MouseClick(object sender, MouseEventArgs e)
        {
            if (cmbSchool.Items.Count <= 0)
            {
                SetSchool(true);
            }
        }
    }
}
